package com.zhu.tool_test.util;

import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import com.zhu.tool_test.dao.SyncTableInfoMapper;
import com.zhu.tool_test.entity.SyncTableInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.poi.ss.formula.functions.T;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.lang.annotation.Annotation;
import java.util.Date;
import java.util.List;

/**
 * @program: data-engine-ep
 * @description: 同步工具类
 * @author: ggBall
 * @create: 2021-02-20 12:28
 **/
@Component
@Slf4j
public class SyncUtils {

    @Autowired
    SyncTableInfoMapper syncTableInfoMapper;
    @Autowired
    SqlSessionTemplate sqlSessionTemplate;

    @Transactional(rollbackFor= RuntimeException.class)
    public void syncTable(Class clazz , Boolean cacheAble) {

        try {

            SqlSessionFactory sqlSessionFactory = sqlSessionTemplate.getSqlSessionFactory();
            Configuration configuration = sqlSessionFactory.getConfiguration();

            // 1. 获取tableName
            String tableName = getTableName(clazz);
            // 2. 根据表名 获取同步条数
            QueryWrapper<SyncTableInfo> syncTableInfoQueryWrapper = new QueryWrapper<>();
            syncTableInfoQueryWrapper.lambda().eq(SyncTableInfo::getTableName,tableName);
            List<SyncTableInfo> syncTableInfos = syncTableInfoMapper.selectList(syncTableInfoQueryWrapper);

            if (null == syncTableInfos || syncTableInfos.size() != 1) {
                log.warn("数据表找不到，数据表{}同步失败",tableName);
                return;
            }
            SyncTableInfo syncTableInfo = syncTableInfos.get(0);
            Long syncNum = syncTableInfo.getSyncNum();
            // 3. 同步条数 +1 和 更新 同步时间
            long newNum = syncNum == null ? 1L : syncNum + 1L;
            syncTableInfo.setLatestTime(new Date());
            // 4. 保存记录
            syncTableInfo.setSyncNum(newNum);
            int update = syncTableInfoMapper.updateById(syncTableInfo);
            if (update > 0) {
                log.info("数据表{}，同步成功",tableName);
            } else {
                log.info("数据表{}，同步失败",tableName);
            }
        }catch (Exception e) {
            log.info("同步失败");
            log.error("{}",e);
            e.printStackTrace();
            throw new RuntimeException();
        }

    }

    private String getTableName(Class<T> clazz) {
        // 1. 先获取 类上的@Table注解值
        Annotation[] annotations = clazz.getAnnotations();
        for (Annotation annotation : annotations) {
            if (annotation instanceof TableName) {
                String value = ((TableName) annotation).value();
                return value;
            }
        }
        // 2. 没有则 获取bean名称
        String beanName = getBeanName(clazz);
        // 3. bean名称 反驼峰化
        return antiCamel(beanName);

    }

    private String getBeanName(Class<T> clazz) {
        // 1. 获取bean名称
        String fullName = clazz.getName();
        if (fullName.isEmpty()) {
            log.warn("beanName 找不到");
            return "";
        }
        String[] nameSplit = fullName.split("\\.");
        String name = nameSplit[nameSplit.length - 1];

        return name;
    }

    private String antiCamel(String beanName) {
        return beanName.replaceAll("[A-Z]", "_$0").toLowerCase();
    }
}
